﻿using System;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;
using MyAlbum.Logging;
using System.Collections.Generic;
using System.IO;
using MyAlbum.Model;
using MyAlbum.Services;
using System.Linq;
namespace PersonalAlbum.Controllers
{

    [OutputCache(Location = OutputCacheLocation.None)]
    public class AccountController : ApplicationController
    {
        public AccountController()
            : this(null, null)
        {
        }

        // This constructor is not used by the MVC framework but is instead provided for ease
        // of unit testing this type. See the comments at the end of this file for more
        // information.

        public AccountController(IFormsAuthentication formsAuth, MembershipProvider provider)
        {
            FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
            Provider = provider ?? Membership.Provider;
        }

        public IFormsAuthentication FormsAuth
        {
            get;
            private set;
        }

        public MembershipProvider Provider
        {
            get;
            private set;
        }


        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Register()
        {
            var model = (PersonalAlbumModel)ViewData.Model;
            if (model.Configuration.AllowAddUsers)
            {
                return View();
            }
            else
            {
                return View("Login");
            }
        }

        [AcceptVerbs(HttpVerbs.Post)]
        //[ValidateAn tiForgeryToken()]
        public ActionResult Register(string username, string email, string password, string confirmPassword)
        {
            var model = (PersonalAlbumModel)ViewData.Model;
            if (model.Configuration.AllowAddUsers)
            {
                if (string.IsNullOrEmpty(username))
                {
                    ViewData.ModelState.AddModelError("username", model.Localize("Global.MissingUserName"));
                }
                if (string.IsNullOrEmpty(password))
                {
                    ViewData.ModelState.AddModelError("password", model.Localize("Global.MissingPassword"));
                }
                if (password != confirmPassword)
                {
                    ViewData.ModelState.AddModelError("password", model.Localize("Global.PasswordNotMatch"));
                }
                if (string.IsNullOrEmpty(email))
                {
                    ViewData.ModelState.AddModelError("email", model.Localize("Global.SupportMissingParams"));
                }
                if (Membership.GetUserNameByEmail(email) != null)
                {
                    ViewData.ModelState.AddModelError("email", model.Localize("Global.EmailAddressExists"));
                }
                /*TODO:check email regex*/
                if (Membership.GetUser(username) != null)
                {
                    ViewData.ModelState.AddModelError("username", model.Localize("Global.UserNameExists"));

                }
                if (ViewData.ModelState.IsValid)
                {
                    MembershipCreateStatus status;
                    var user = Membership.CreateUser(username, password, email, null, null, !model.Configuration.ValidateNewUsersEmail, out status);
                    WebLogger.Trace("user created");
                    Roles.AddUserToRole(user.UserName, RolesManager.User);
                    if (model.Configuration.ValidateNewUsersEmail)
                    {
                        if (RegistrationRequestsManager.CheckIfExists(email))
                        {
                            ViewData.ModelState.AddModelError("email", model.Localize("Global.EmailAddressExists"));
                            return View();
                        }
                        PostOffice po = new PostOffice(model.Configuration);
                        var link = RegistrationRequestsManager.GenerateLink(email, username);
                        po.SendConfirmationEmail(email, username, link, this.ControllerContext.RequestContext);
                        WebLogger.Trace("email sent");
                        return View("ConfirmRegistration");
                    }
                    else
                    {
                        return View("RegistrationComplete");
                    }

                }
                else
                {
                    return View();
                }
            }
            else
            {
                return View("Login");
            }
        }

        public ActionResult ConfirmRegistration(string confirmationCode)
        {
            WebLogger.Trace("confirm regist");
            try
            {
                string userName;
                if (RegistrationRequestsManager.ValidateAndDelete(confirmationCode, out userName))
                {
                    WebLogger.Trace("validated");
                    var user = Membership.GetUser(userName);
                    user.IsApproved = true;
                    Membership.UpdateUser(user);
                    WebLogger.Trace("updated");
                    return View("RegistrationComplete");
                }else{
WebLogger.Trace("could not validate");
                }
            }
            catch (Exception e1)
            {
                WebLogger.LogError(e1, "registering user");
            }
            return View("RegistrationFailure");
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Lang(string lang, string returnUrl)
        {
            var model = (PersonalAlbumModel)ViewData.Model;
            string l;
            if (string.IsNullOrEmpty(lang) ||
                !model.Configuration.GetAvailableLanguages().Contains(lang))
            {
                WebLogger.Warning("The language value \"" +
                    lang + "\" was not found");
                l = model.Configuration.DefaultLanguage;
            }
            else
            {
                l = lang;
            }
            model.Languages.Language = l;
            if (returnUrl == null)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                return Redirect(returnUrl);
            }
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ViewResult Index()
        {
            return View("Login");
        }
        [AcceptVerbs(HttpVerbs.Get)]
        public ViewResult Login()
        {
            return View(ViewData.Model);
        }

        /// <summary>
        /// Ajax action
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="rememberMe"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Post)]
        //[ValidateAn tiForgeryToken()]
        public ActionResult Login(string username, string password, bool? rememberMe, string returnUrl)
        {
            ActionResult result;
            PersonalAlbumModel model = ViewData.Model as PersonalAlbumModel;

            try
            {
                var redirect = returnUrl ?? "/default.aspx";
                // Basic parameter validation
                if (String.IsNullOrEmpty(username))
                {
                    if (Request.IsAjaxRequest())
                    {
                        result = Json(new { invalid = "true", message = model.Localize("Global.MissingUserName") });
                    }
                    else
                    {
                        ViewData.ModelState.AddModelError("username", model.Localize("Global.MissingUserName"));
                        result = View();
                    }
                }
                else if (String.IsNullOrEmpty(password))
                {
                    if (Request.IsAjaxRequest())
                    {
                        result = Json(new { invalid = "true", message = model.Localize("Global.MissingPassword") });
                    }
                    else
                    {
                        ViewData.ModelState.AddModelError("password", model.Localize("Global.MissingPassword"));
                        result = View();
                    }
                }
                else
                {
                    // Attempt to login

                    bool loginSuccessful = Provider.ValidateUser(username, password);
                    if (loginSuccessful)
                    {
                        FormsAuthentication.SetAuthCookie(username, false);
                        if (Request.IsAjaxRequest())
                        {
                            result = Json(new { success = "true", returnUrl = redirect });
                        }
                        else
                        {
                            result = new RedirectResult(redirect);
                        }
                    }
                    else
                    {
                        if (Request.IsAjaxRequest())
                        {
                            result = Json(new { invalid = "true", message = model.Localize("Global.BadUserNameOrPassword") });
                        }
                        else
                        {
                            ViewData.ModelState.AddModelError("username", model.Localize("Global.BadUserNameOrPassword"));
                            result = View();
                        }
                    }
                }

                // If we got this far, something failed, redisplay form
                // ViewData["rememberMe"] = rememberMe;

            }
            catch (Exception e1)
            {
                WebLogger.LogError(e1, "login");
                if (Request.IsAjaxRequest())
                {
                    result = Utils.JavascriptError("");
                }
                else
                {
                    model.ErrorMessage = model.Localize("Global.Error");
                    result = View();
                }
            }
            return result;
        }

        public RedirectToRouteResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }


    }


    // The FormsAuthentication type is sealed and contains static members, so it is difficult to
    // unit test code that calls its members. The interface and helper class below demonstrate
    // how to create an abstract wrapper around such a type in order to make the AccountController
    // code unit testable.

    public interface IFormsAuthentication
    {
        void SetAuthCookie(string userName, bool createPersistentCookie);
        void SignOut();
    }

    public class FormsAuthenticationWrapper : IFormsAuthentication
    {
        public void SetAuthCookie(string userName, bool createPersistentCookie)
        {
            FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
        }
        public void SignOut()
        {
            FormsAuthentication.SignOut();
        }
    }


}
